﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace AiMoWindows.CodeScripts.Analysis
{
    static class UsingFix
    {
        // 修复Usings
        public static void PerformFix(CompilationUnitSyntax compilation, SyntaxConvertResult result)
        {
            if (!UsingFixLibrary.Inited) throw new Exception("Debug Error: CodeUsingFixer not inited");
            UsingFixLibrary fixer = new UsingFixLibrary();
            foreach (UsingDirectiveSyntax usingDirective in compilation.Usings)
            {
                string name = usingDirective.Name?.ToString() ?? "";
                fixer.SetDefaultUsing(name);
            }
            foreach (SyntaxNode node in compilation.DescendantNodes())
            {
                //System.Diagnostics.Debug.WriteLine($"SyntaxNode\n    {node} _ {node.GetType()}");
                switch (node)
                {
                    case ObjectCreationExpressionSyntax objectCreationExpressionSyntax:
                        {
                            fixer.AddTypeSyntax(objectCreationExpressionSyntax.Type);
                            break;
                        }
                    case MemberAccessExpressionSyntax memberAccessExpressionSyntax:
                        {
                            ExpressionSyntax expression = memberAccessExpressionSyntax.Expression;
                            if (expression is IdentifierNameSyntax nameSyntax)
                            {
                                //Debug.WriteLine($"MemberAccessExpression Expression\n    {nameSyntax}");
                                fixer.AddKeyword(nameSyntax.ToString());
                            }
                            SimpleNameSyntax name = memberAccessExpressionSyntax.Name;
                            //Debug.WriteLine($"MemberAccessExpression Name\n    .{name}");
                            fixer.AddKeyword($".{name}");
                            break;
                        }
                    case VariableDeclarationSyntax variableDeclarationSyntax:
                        {
                            TypeSyntax typeSyntax = variableDeclarationSyntax.Type;
                            fixer.AddTypeSyntax(typeSyntax);
                            break;
                        }
                    case InvocationExpressionSyntax invocationExpressionSyntax:
                        {
                            ExpressionSyntax expression = invocationExpressionSyntax.Expression;
                            if (expression is IdentifierNameSyntax nameSyntax)
                            {
                                //Debug.WriteLine($"InvocationExpressionSyntax\n    {nameSyntax}");
                                fixer.AddKeyword(nameSyntax.ToString());
                            }
                            break;
                        }
                    case GenericNameSyntax genericNameSyntax:
                        {
                            // 表示泛型名称的语法节点的类。
                            fixer.AddTypeSyntax(genericNameSyntax);
                            break;
                        }
                    case TypeArgumentListSyntax typeArgumentListSyntax:
                        {
                            foreach (TypeSyntax typeSyntax in typeArgumentListSyntax.Arguments)
                            {
                                fixer.AddTypeSyntax(typeSyntax);
                            }
                            break;
                        }
                    case DeclarationExpressionSyntax declarationExpressionSyntax:
                        {
                            if (declarationExpressionSyntax.Type is IdentifierNameSyntax nameSyntax)
                            {
                                //System.Diagnostics.Debug.WriteLine($"DeclarationExpressionSyntax\n    {nameSyntax}");
                                fixer.AddKeyword(nameSyntax.ToString());
                            }
                            break;
                        }
                    case ArrayTypeSyntax arrayTypeSyntax:
                        {
                            // 表示数组类型的语法节点的类。
                            fixer.AddTypeSyntax(arrayTypeSyntax);
                            break;
                        }
                    case BaseListSyntax baseListSyntax:
                        {
                            // 表示class的继承
                            foreach (BaseTypeSyntax type in baseListSyntax.Types)
                            {
                                fixer.AddTypeSyntax(type.Type);
                            }
                            break;
                        }
                    case ForEachStatementSyntax forEachStatementSyntax:
                        {
                            fixer.AddTypeSyntax(forEachStatementSyntax.Type);
                            break;
                        }
                    case IsPatternExpressionSyntax isPatternExpressionSyntax:
                        {
                            if (isPatternExpressionSyntax.Pattern is DeclarationPatternSyntax patternSyntax)
                            {
                                fixer.AddTypeSyntax(patternSyntax.Type);
                            }
                            break;
                        }
                    case BinaryExpressionSyntax binaryExpressionSyntax:
                        {
                            if (binaryExpressionSyntax.IsKind(SyntaxKind.IsExpression) || binaryExpressionSyntax.IsKind(SyntaxKind.AsExpression))
                            {
                                if (binaryExpressionSyntax.Right is TypeSyntax typeSyntax)
                                {
                                    fixer.AddTypeSyntax(typeSyntax);
                                }
                            }
                            break;
                        }
                    case ParameterSyntax parameterSyntax:
                        {
                            fixer.AddTypeSyntax(parameterSyntax.Type);
                            break;
                        }
                    default:
                        {
                            //System.Diagnostics.Debug.WriteLine($"SyntaxNode\n    {node} _ {node.GetType()}");
                            break;
                        }
                }
            }

            //这是从原文提取Usings
            //result.Usings.AddLinesFromSourceText(unitSyntax.Usings.FullSpan, sourceText);
            //这是使用Fixer
            //result.Usings.Add(CodeUsingFixer.AiMoVersionMarker);
            result.Usings.AddRange(fixer.GetResultUsings());
        }
        static void AddTypeSyntax(this UsingFixLibrary fixer, TypeSyntax? type)
        {
            switch (type)
            {
                case IdentifierNameSyntax nameSyntax:
                    fixer.AddKeyword(nameSyntax.ToString());
                    break;
                case ArrayTypeSyntax arraySyntax:
                    fixer.AddTypeSyntax(arraySyntax.ElementType);
                    break;
                case GenericNameSyntax genericNameSyntax:
                    fixer.AddTypeSyntax(genericNameSyntax.TypeArgumentList.Arguments.FirstOrDefault());
                    break;
            }
        }
    }
}
